// ----------------------------------------------------------------------------
// serialize_allocator.h
// ----------------------------------------------------------------------------
/*
 Description:
 .
 */
#pragma once
#include <stddef.h>
#include <fw/base/serialize/serialize_status.h>
#include <fw/base/core/assertion.h>
#include <fw/base/core/noncopyable.h>

namespace fw
{
	class SerializeType;
	
	class SerializeAllocator : private NonCopyable
	{
	private:
		static const int	kMaxEntries = 100;
		
		struct Block
		{
			const SerializeType*	m_dstType;
			const SerializeType*	m_srcType;
			const char*				m_srcData;
			int						m_count;
			size_t					m_offset;
		}; // struct Block
		
		Block						m_blocks	[kMaxEntries];
		int							m_blockCount;
		
		const char*					m_pointers	[kMaxEntries];
		int							m_pointerCount;
		
		char*						m_data;
		size_t						m_offset;
		size_t						m_size;
		
	public:
		
		SerializeAllocator();
		SerializeAllocator(char* data, size_t size);
		
		void						SetBuffer	(char* data, size_t size);
		
		char*						Alloc		(const SerializeType* dstType,
												 const SerializeType* srcType,
												 const char*		  srcData,
												 int				  count);
		
		size_t						GetSize() const
		{
			return m_offset;
		}
		
		int							GetCount() const
		{
			return m_blockCount;
		}
		
		void						StorePointerLocation	(const char* data);
		int							GetPointerLocationCount	() const;
		const char*					GetPointerLocation		(int index) const;
		
		void						ConvertAll();
		
	private:
		
		Block*						FindBlock	(const SerializeType* dstType, const SerializeType* srcType, const char* srcData, int count);
		Block*						AddBlock	(const SerializeType* dstType, const SerializeType* srcType, const char* srcData, int count);
		
		const Block*				GetBlock	(int index) const
		{
			FW_ASSERT(index<kMaxEntries);
			return &m_blocks[index];
		}
		
		SerializeStatus				ConvertBlock(const Block* block);
		
		char*						GetDstPtr	(const Block* block) const;
		
	}; // class SerializeAllocator
	
} // namespace fw
